<?php

/**
 * @file library/Zwe/Model/User.php
 * Il modello dell'utente.
 *
 * @category    Zwe
 * @package     Zwe_Model
 * @version     $Id
 */

/**
 * Il modello dell'utente.
 * Gestisce anche azioni comuni come validare un login.
 *
 * @uses        Zwe_Model
 * @category    Zwe
 * @package     Zwe_Model
 */
class Zwe_Model_User extends Zwe_Model
{
    protected $_name = 'user';
    protected $_primary = 'IDUser';

    /**
     * L'adapter per l'autenticazione.
     *
     * @var Zend_Auth_Adapter_DbTable
     */
    protected static $AuthAdapter = null;

    /**
     * L'utente loggato.
     *
     * @var Zend_Auth_Result
     */
    protected static $AuthResult = null;

    /**
     * Getter dell'adapter per l'autenticazione, opportunamente modificato per gestire la login del sito.
     *
     * @static
     * @return Zend_Auth_Adapter_DbTable L'adapter per la login
     */
    public static function getAuthAdapter()
    {
        if(!isset(self::$AuthAdapter))
        {
            self::$AuthAdapter = new Zend_Auth_Adapter_DbTable(Zend_Db_Table::getDefaultAdapter());

            self::$AuthAdapter->setTableName('user')
                              ->setIdentityColumn('Email')
                              ->setCredentialColumn('Password')
                              ->setCredentialTreatment("SHA1(CONCAT(?, Salt)) AND Activated = '1'");
        }

        return self::$AuthAdapter;
    }

    /**
     * Getter del risultato della login.
     *
     * @static
     * @return Zend_Auth_Result
     */
    public static function getAuthResult()
    {
        return self::$AuthResult;
    }

    /**
     * Ritorna se l'email e la password passate corrispondono a un utente valido.
     *
     * @static
     * @param string $Email L'email dell'utente che si vuole loggare
     * @param string $Password La password dell'utente che si vuole loggare
     * @return bool Se lo login è andata a buon fine o meno
     */
    public static function isValidLogin($Email, $Password)
    {
        $Auth = Zend_Auth::getInstance();
        $Adapter = self::getAuthAdapter();

        $Adapter->setIdentity($Email);
        $Adapter->setCredential($Password);

        self::$AuthResult = $Auth->authenticate($Adapter);

        if(self::$AuthResult->isValid())
        {
            $Auth->getStorage()->write(self::getUserById($Adapter->getResultRowObject()->IDUser));
            return true;
        }
        else
        {
            return false;
        }
    }

    /**
     * @static
     * @param int $IDUser
     * @return Zwe_Model_User
     */
    public static function getUserById($IDUser)
    {
        $User = new self();
        return $User->fetchRowAndSet("IDUser = '$IDUser'");
    }

    public static function getUserByEmail($Email)
    {
        $User = new self();
        return $User->fetchRowAndSet("Email = '$Email'");
    }

    /**
     * Invia la mail per il reset della password.
     * Se l'utente non viene trovato, o se ci sono stati problemi nell'invio della mail, ritorna false catchando l'eccezione.
     *
     * @static
     * @param string $Email L'email dell'utente
     * @return bool Se l'invio della mail è andato a buon fine o meno
     * @todo Impostare la creazione automatica per l'url di reset della password.
     * @todo Impostare la creazione automatica dell'url del sito (togliere il parametro siteUrl)
     */
    public static function sendResetPassword($Email)
    {
        try
        {
            $User = self::getUserByEmail($Email);
            $Mail = new Zend_Mail();
            $Mail->setFrom(Zend_Registry::get('parameters')->registry->email, Zend_Registry::get('parameters')->registry->emailName);
            $Mail->addTo($User->Email, $User->Name);
            $Mail->setSubject("Recover your password");
            $Mail->setBodyText("This mail has been generated by a request of resetting your password on " . Zend_Registry::get('parameters')->registry->siteTitle . " website.\nIf you didn't request it, please delete this email and nothing will be done.\n\nOtherwise, if you want to reset your password, please visit this link:\n\n" . Zend_Registry::get('parameters')->registry->siteUrl . "/login/recoverPassword/" . $User->IDUser . "/" . $User->Salt . "\n\nWe also remind you that it's better to choose a password that is easy to remember, but not so easy to be guessed!");
            $Mail->send();

            return true;
        }
        catch(Exception $E)
        {
            return false;
        }
    }

    public static function changePassword($User, $Password, $Salt = null)
    {
        $TheUser = new self();

        $Data = array('Salt' => new Zend_Db_Expr('SHA1(' . mt_rand() . ')'));
        $Changed = (boolean) $TheUser->update($Data, "IDUser = '$User'" . (isset($Salt) ? " AND Salt = '$Salt'" : ""));

        if($Changed)
        {
            $Data = array('Password' => new Zend_Db_Expr("SHA1(CONCAT('$Password', Salt))"));
            return (boolean) $TheUser->update($Data, "IDUser = '$User'");
        }

        return false;
    }

    public static function addUser($Email, $Password)
    {
        $TheUser = new self();

        $Data = array('Email' => $Email, 'Salt' => new Zend_Db_Expr("SHA1('" . mt_rand() . "')"), 'Password' => new Zend_Db_Expr("SHA1(CONCAT('$Password', Salt))"), 'RegistrationDate' => new Zend_Db_Expr('NOW()'));
        $IDUser = $TheUser->insert($Data);

        if($IDUser)
        {
            $Mail = new Zend_Mail();
            $Mail->setFrom(Zend_Registry::get('parameters')->registry->email, Zend_Registry::get('parameters')->registry->emailName);
            $Mail->addTo($Email);
            $Mail->setSubject("New registration");
            $Mail->setBodyText("Welcome to the " . Zend_Registry::get('parameters')->registry->siteTitle . " website.\n\nThis is the recap of your credentials:\nEmail: $Email\nPassword: $Password\n\nPlease, consider to save this email to remember your credentials.\n\nTo activate your account you have to click on this link: " . Zend_Registry::get('parameters')->registry->siteUrl . "/login/confirm/$IDUser/" . sha1($IDUser));
            $Mail->send();
        }

        return $IDUser;
    }

    public static function confirmUser($IDUser, $Salt)
    {
        $TheUser = new self();

        $Data = array('Activated' => '1');
        return $TheUser->update($Data, "IDUser = '$IDUser' AND SHA1('$IDUser') = '$Salt'");
    }

    public static function searchUser($Search)
    {
        $TheUser = new self();

        $Users = $TheUser->fetchAll("Name LIKE '%$Search%' OR Surname LIKE '%$Search%'");
        $Ret = array();

        if($Users)
        {
            foreach($Users as $User)
            {
                $TheUser = new self();
                $Ret[] = $TheUser->copyFromDb($User);
            }
        }

        return $Ret;
    }

    public function canModify()
    {
        return Zend_Auth::getInstance()->hasIdentity() && Zend_Auth::getInstance()->getIdentity()->IDUser == $this->IDUser;
    }

    protected function getName()
    {
        return $this->_data['Email'];
    }

    protected function getUrl()
    {
        return $this->IDUser . ' ' . $this->_data->Name . ' ' . $this->Surname;
    }

    public function __toString()
    {
        return $this->getName();
    }

    public function __get($Name)
    {
        if('Name' == $Name)
            return $this->getName();
        elseif('Url' == $Name)
            return $this->getUrl();
        else
            return parent::__get($Name);
    }
}

?>